package top.hcode.hoj.service.admin.course;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import top.hcode.hoj.dao.LinkLoader;
import top.hcode.hoj.dao.common.FileEntityService;
import top.hcode.hoj.dao.course.LessonDao;
import top.hcode.hoj.dao.course.LessonHandoutDao;
import top.hcode.hoj.dao.course.LessonWorkQuestionDao;
import top.hcode.hoj.dao.course.QuestionDao;
import top.hcode.hoj.mapper.CourseMapper;
import top.hcode.hoj.pojo.dto.*;
import top.hcode.hoj.pojo.entity.course.*;
import top.hcode.hoj.utils.AliyunOSSUtils;
import top.hcode.hoj.utils.Constants;
import top.hcode.hoj.utils.ShiroUtils;

import java.util.List;

/**
 * @author orangej
 * @since 2024/12/18
 */
@Component
public class AdminLessonService {
    @Autowired
    private LessonDao lessonDao;
    @Autowired
    private QuestionDao questionDao;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private LessonHandoutDao handoutDao;
    @Autowired
    private LessonWorkQuestionDao workQuestionDao;

    @Autowired
    private LinkLoader cascadeLoader;
    @Autowired
    private FileEntityService fileEntityService;
    @Autowired
    private AdminQuestionService questionService;

    public IPage<Lesson> getLessonList(AdminQueryLessonDTO dto) {
        IPage<Lesson> pager = new Page<>(dto.getCurrentPage(), dto.getLimit());

        QueryWrapper<Lesson> query = Wrappers.query();
        String keyword = dto.getKeyword();
        if (dto.getCourseId() != null) {
            query.eq("course_id", dto.getCourseId());
        }
        if (dto.getSectionId() != null) {
            query.eq("section_id", dto.getSectionId());
        }
        if (Strings.isNotBlank(keyword)) {
            query.and(c -> c.like("lesson_name", keyword).or().like("description", keyword));
        }

        query.orderByAsc("course_id", "section_id", "sort_order");

        pager = lessonDao.page(pager, query);
        cascadeLoader.loadCourse(pager.getRecords());
        cascadeLoader.loadCourseSection(pager.getRecords());
        return pager;
    }

    @Transactional
    public Lesson saveLesson(Lesson lesson) {
        if (lesson.getId() == null) {
            // 新增lesson
            Validator.validateNotNull(lesson.getCourseId(), "课程不能为空");
            Validator.validateNotNull(lesson.getSectionId(), "章节不能为空");
            Validator.validateNotNull(lesson.getLessonName(), "课程名称不能为空");
            Validator.validateNotNull(lesson.getDescription(), "课程描述不能为空");

            if (lesson.getSortOrder() == null) {
                lesson.setSortOrder(lessonDao.getNextSortOrder(lesson.getSectionId()));
            }

            Course course = courseMapper.selectById(lesson.getCourseId());
            lesson.setUid(course.getUid());
            lesson.setGid(course.getGid());
        }

        String videoUrl = lesson.getVideoUrl();
        if (Strings.isNotBlank(videoUrl) && videoUrl.contains("oistudy.oss-cn-hangzhou.aliyuncs.com")) {
            videoUrl = videoUrl.replace("oistudy.oss-cn-hangzhou.aliyuncs.com", "oistudy-oss.rui-ya.com");
            String key = StrUtil.subAfter(videoUrl, "com/", true);
            OssFileInfoDTO dto = AliyunOSSUtils.getVideoInfo(key);

            // 更新视频时长
            lesson.setDuration(dto.getDuration());
            lesson.setVideoUrl(videoUrl);

            // 保存新的视频文件记录
            fileEntityService.saveOssFile(ShiroUtils.getUid(), "course_video", videoUrl, dto.getSize());
        }

        if (lesson.getId() != null) {
            Lesson dbo = lessonDao.getById(lesson.getId());
            if (Strings.isNotBlank(dbo.getVideoUrl())) {
                // 删除旧的视频文件
                fileEntityService.updateFileToDeleteByFilePath(dbo.getVideoUrl());
            }
        }

        lessonDao.saveOrUpdate(lesson);
        return lesson;
    }

    @Transactional
    public void deleteLesson(Long id) {
        // todo 删除相关资料
        Lesson lesson = lessonDao.getById(id);
        if (lesson == null) {
            return;
        }

        if (Strings.isNotBlank(lesson.getVideoUrl())) {
            fileEntityService.updateFileToDeleteByFilePath(lesson.getVideoUrl());
        }

        lessonDao.removeById(id);
    }

    public Lesson getLessonDetail(Long id) {
        Lesson lesson = lessonDao.getById(id);
        cascadeLoader.loadCourse(lesson);
        cascadeLoader.loadCourseSection(lesson);
        cascadeLoader.loadLessonHandouts(lesson);
        return lesson;
    }

    @Transactional
    public LessonHandout saveHandout(LessonHandout handout) {
        if (handout.getId() == null) {
            Validator.validateNotNull(handout.getLessonId(), "课时不能为空");
            Validator.validateNotNull(handout.getTitle(), "资料名称不能为空");
            Validator.validateNotNull(handout.getFileUrl(), "资料路径不能为空");

            Lesson lesson = lessonDao.getById(handout.getLessonId());
            handout.setCourseId(lesson.getCourseId());
            if (Strings.isBlank(handout.getType())) {
                handout.setType(StrUtil.removePrefix(Files.getSuffix(handout.getFileUrl()), "."));
            }
        }

        handoutDao.saveOrUpdate(handout);
        lessonDao.refreshHandoutCount(handout.getLessonId());
        return handout;
    }

    @Transactional
    public void deleteHandout(Long id) {
        LessonHandout handout = handoutDao.getById(id);
        if (handout == null) {
            return;
        }

        if (Strings.isNotBlank(handout.getFileUrl())) {
            fileEntityService.updateFileToDeleteByFilePath(handout.getFileUrl());
        }

        handoutDao.removeById(id);
        lessonDao.refreshHandoutCount(handout.getLessonId());
    }

    public List<LessonWorkQuestion> getLessonWorkList(QueryLessonWorkDTO dto) {
        Long lessonId = dto.getLessonId();
        String type = dto.getWorkType();    // lesson or home

        QueryWrapper<LessonWorkQuestion> query = new QueryWrapper<>();
        query.eq("lesson_id", lessonId);
        if (Strings.isNotBlank(type)) {
            query.eq("work_type", type);
        }
        query.orderByAsc("sort_order");

        List<LessonWorkQuestion> records = workQuestionDao.list(query);
        cascadeLoader.loadLinks(records, "question", "problem");
        return records;
    }

    @Transactional
    public void deleteLessonWork(Long id) {
        LessonWorkQuestion workQuestion = workQuestionDao.getById(id);
        if (workQuestion == null) {
            return;
        }
        workQuestionDao.removeById(id);
        lessonDao.refreshWorkCount(workQuestion.getLessonId());
    }

    @Transactional
    public LessonWorkQuestion saveLessonWork(LessonWorkQuestion workQuestion) {
        if (workQuestion.getId() == null) {
            // 处理新增的逻辑，必填字段：lessonId, questionId || problemId, workType
            Validator.validateNotNull(workQuestion.getLessonId(), "课时不能为空");
            Validator.validateNotNull(workQuestion.getWorkType(), "作业类型不能为空");

            Long questionId = workQuestion.getQuestionId();
            Long problemId = workQuestion.getProblemId();
            Validator.validateTrue(questionId != null || problemId != null, "题目不能为空");

            if (questionId != null) {
                Question question = questionDao.getById(questionId);
                Validator.validateTrue(question != null, "题目不存在");
                workQuestion.setQuestionType(question.getType());
            } else {
                workQuestion.setQuestionType(Constants.QuestionType.PROGRAM.getType());
            }

            Integer order = workQuestionDao.nextSortOrder(workQuestion.getLessonId(), workQuestion.getWorkType());
            workQuestion.setSortOrder(order);
        }

        // save
        workQuestionDao.saveOrUpdate(workQuestion);

        // refresh lesson work count
        lessonDao.refreshWorkCount(workQuestion.getLessonId());

        return workQuestion;
    }

    /**
     * 添加新的习题，同时保存作业习题
     *
     * @param form 带有workType的question
     * @return Question
     */
    @Transactional
    public Question saveQuestion(SaveQuestionDTO form) {
        // 调用 AdminQuestionService 的方法，完成保存习题的逻辑
        Question question = questionService.saveQuestion(form);

        // 处理作业习题的逻辑
        if (Strings.isNotBlank(form.getWorkType())) {
            Validator.validateTrue(Lang.list("lesson", "home").contains(form.getWorkType()), "作业类型错误");

            int count = workQuestionDao.count(new QueryWrapper<LessonWorkQuestion>()
                    .eq("question_id", question.getId()));
            Validator.validateTrue(count == 0, "该习题已经存在于作业中");

            LessonWorkQuestion workQuestion = new LessonWorkQuestion();
            workQuestion.setQuestionId(question.getId());
            workQuestion.setProblemId(null);
            workQuestion.setWorkType(form.getWorkType());
            saveLessonWork(workQuestion);
        }
        return question;
    }

    @Transactional
    public void saveLessonWorkSort(BaseIdListDTO dto) {
        List<Long> idList = dto.getIdList();
        for (int i = 0; i < idList.size(); i++) {
            Long id = idList.get(i);
            int sort = i+1;
            workQuestionDao.update(new UpdateWrapper<LessonWorkQuestion>().eq("id", id).set("sort_order", sort));
        }
    }
}
